/////////////////////////////////////////////////////////////////////////////
// Filename: Matrix4.h
// Description: 4x4 matrix class
/////////////////////////////////////////////////////////////////////////////

#ifndef MATRIX4_H
#define MATRIX4_H

#include "Vector3h.h"
#include <string.h>

//treat Vector3h as a ordinary vector4
typedef Vector3h vector4;

class Matrix4 {
private:
	float m[16];

public:
	Matrix4() {identity();};
	Matrix4(const float mm[16]) {set(mm);}
	Matrix4(const Matrix4 &m) {set(m.m);}

	//set matrix with row vectors (use transpose to set column vectors)
	Matrix4(const vector4 &a,const vector4 &b,
		const vector4 &c, const vector4 &d=vector4(0,0,0,1));

	//identity matrix
	Matrix4  &identity() {
		clear();(*this)(0,0)=(*this)(1,1)=(*this)(2,2)=(*this)(3,3)=1.0;return *this;
	}

	void set(const float mm[16]) {memcpy(m,mm,16*sizeof(float));}

	//set to zero
	void clear() {memset(m,0,16*sizeof(float));}

	//() operator to access elements of the matrix
	float   &operator ()(int r,int k) {return m[4*k + r];}  
	const float  &operator ()(int r,int k) const {return m[4*k + r];}

	//get the internal representation, for use with OpenGL
	float* get_data(){return m;}

	//matrix multiplication 
	Matrix4  operator *(const Matrix4 &T) const; 
	Matrix4  &operator *=(const Matrix4 &T) {return (*this)=(*this)*T;}

	//elementwise mult. with scalar
	Matrix4  operator *(float f) const;        
	Matrix4  &operator *=(float f);

	//Matrix4*vector4 
	vector4  operator *(const vector4 &p) const;

	//returns transposed matrix
	Matrix4  transpose() const;


	/////////////////////////////////////////////////////////////////////////////
	//Obs! det() and inv() works ONLY if the last line of the matrix is (0,0,0,1)
	/////////////////////////////////////////////////////////////////////////////

	double det() const;
	Matrix4 inv() const;

};


#endif 

/////////////////////////////////////////////////////////////////////////////
//                               END OF FILE                               //
/////////////////////////////////////////////////////////////////////////////
